package fellowship;

import java.awt.Button;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import uniqueEquipment.Anduril;
import equipment.*;
import main.DieRoll;
import main.Equipment;
import main.Hero;
import main.UI;
import main.Unit;
import main.Utils;

public class Aragorn extends Hero {
	public Equipment[] equipChoices = {new Armor(), new Bow(), new ElvenCloak(), new Anduril()};
	public boolean hasUsedFreeMight = false;
	
	public Aragorn(int id, int armyIndex, int x, int y) {
		this.strength = 4;
		this.defense = 5;
		this.attacks = 3;
		this.wounds = 3;
		this.courage = 6;
		this.fightValue = 6;
		this.shootValue = 3;
		
		this.might = 3;
		this.will = 3;
		this.fate = 3;
		this.initWorking();

		this.baseMove = 6.0;
		this.move = 6.0;
		this.moveLeft = 6.0;
		
		this.id = id;
		this.name = "Aragorn";
		this.race = "Man";
		this.x = x;
		this.y = y;
		this.armyIndex = armyIndex;
	}
	
	// Currently only supports cloning at beginning of game (missing some variables that can change throughout game)
	public Aragorn clone() {
		Aragorn copy = new Aragorn(this.id, this.armyIndex, this.x, this.y);
		copy.strength = this.strength;
		copy.defense = this.defense;
		copy.attacks = this.attacks;
		copy.wounds = this.wounds;
		copy.courage = this.courage;
		copy.fightValue = this.fightValue;
		copy.shootValue = this.shootValue;
				
		copy.move = this.move;
		copy.moveLeft = this.moveLeft;
		copy.shootRange = this.shootRange;
		copy.shootStrength = this.shootStrength;
		copy.moveNeededToShoot = this.moveNeededToShoot;
		copy.hasShot = this.hasShot;
		
		copy.equipmentList = new ArrayList<Equipment>();
		for(Equipment e : this.equipmentList){
			copy.equipmentList.add(e);
		}
		
		copy.supporters = new ArrayList<Unit>();
		for(Unit u : this.supporters){
			copy.supporters.add(u);
		}
		
		copy.battle = this.battle;
		copy.game = this.game;
		
		return copy;
	}

	public Equipment[] getEquipChoices() {
		return this.equipChoices;
	}
	
	// Both of these are updated for the Mighty Hero rule
	public void useMight(int numDice) {
		if (!this.hasUsedFreeMight && numDice >= 1){
			numDice -= 1;
			this.hasUsedFreeMight = true;
		}
		this.mightLeft -= numDice;
	}
	public int getMight() {
		if (!hasUsedFreeMight)
			return mightLeft + 1;
		else
			return mightLeft;
	}
	public void refresh(){
		if (!layingDown)
			this.moveLeft = this.move;
		else
			this.moveLeft = 1;
		this.hasShot = false;
		this.hasFought = false;
		this.passedChargeTest = false;
		this.passedBrokenTest = false;
		this.tempTerrifying = isTerrifying;
		this.isTransfixed = false;
		this.hasUsedMagic = false;
		this.supporting = null;
		this.supporters = new ArrayList<Unit>();
		this.hasRetreated = true;
		
		//Unique to Aragorn: Mighty Hero rule
		this.hasUsedFreeMight = false;
		
		for (Equipment e : this.equipmentList){
			if (e.options != null)
				e.options.select(0);
		}
		for (Button refreshButton : this.refreshButtons) {
			refreshButton.dispatchEvent(new MouseEvent(refreshButton, MouseEvent.MOUSE_CLICKED, 
					System.currentTimeMillis(), 0, 10, 10, 1, false));
		}
		this.refreshButtons.clear();
	}

	// Both of these need to be modified for whether he is holding Anduril or not (Max of 4+ to wound)
	public void strike(Unit target, Button doneStriking) {
		game.myUI.storeVisibleComponents();
		game.myUI.disableComponents();
		
		int effectiveStrengthTemp;
		// If we have Anduril, maximum required to wound is 4+, which is equivalent to saying we have equal strength and defense
		if (this.hasEquipment(new Anduril()))
			effectiveStrengthTemp = Math.max(this.getStrength(), target.getDefense());
		else
			effectiveStrengthTemp = this.getStrength();
		
		final int effectiveStrength = effectiveStrengthTemp;
		
		int neededToWound = Utils.neededToWound(effectiveStrength, target.getDefense());
		DieRoll strikeRoll = new DieRoll(this, game.myUI.dim.width-200, game.myUI.dim.height/2-130, 
										 this.woundBonus, neededToWound+"+ to wound", game.myUI);
		
		// Can't use might for strike
		if (!strikeRoll.isModifiable()) {
			strikeRoll.cleanup();
			UI.messageLog.add(this.toChoiceString() + " is attacking " 
					+ target.toChoiceString() + " with roll of " + strikeRoll.getRoll());
			target.takeStrike(effectiveStrength, strikeRoll.getRoll());
			if (game.myUI.getByName("fateButton") == null) {
				game.myUI.reenableComponents();
				game.myUI.disableMight();
				if (doneStriking != null) {
					System.out.println("DISPATCHING1");
					doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
												System.currentTimeMillis(), 0, 10, 10, 1, false));
				}
			}
			else {
				for (Component c : game.myUI.getComponents()) {
					if (c instanceof Button && ((Button)c).getLabel().equals("Don't use fate")) {
						((Button)c).addActionListener(new ActionListener() {
							public void actionPerformed(ActionEvent e) {
								game.myUI.reenableComponents();
								game.myUI.disableMight();
								if (doneStriking != null){
									System.out.println("DISPATCHING2");
									doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
											System.currentTimeMillis(), 0, 10, 10, 1, false));
								}
							}
						});
					}
					else if (c instanceof Button && ((Button)c).getLabel().equals("Use fate")) {
						((Button)c).addActionListener(new ActionListener() {
							public void actionPerformed(ActionEvent e) {
								game.myUI.doneUsingMight.addActionListener(new ActionListener() {
									public void actionPerformed(ActionEvent e) {
										game.myUI.reenableComponents();
										game.myUI.disableMight();
										if (doneStriking != null) {
											System.out.println("DISPATCHING3");
											doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
													System.currentTimeMillis(), 0, 10, 10, 1, false));
										}
									}
								});
							}
						});
					}
				}
			}
		}
		else {
			ActionListener mightDone = new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					strikeRoll.cleanup();
					UI.messageLog.add(toChoiceString() + " is attacking " 
							+ target.toChoiceString() + " with roll of " + strikeRoll.getRoll());
					target.takeStrike(effectiveStrength, strikeRoll.getRoll());
					if (game.myUI.getByName("fateButton") == null) {
						game.myUI.reenableComponents();
						game.myUI.disableMight();
						if (doneStriking != null){
							System.out.println("DISPATCHING4");
							doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
									System.currentTimeMillis(), 0, 10, 10, 1, false));
						}
					}
					else {
						for (Component c : game.myUI.getComponents()) {
							if (c instanceof Button && ((Button)c).getLabel().equals("Don't use fate")) {
								((Button)c).addActionListener(new ActionListener() {
									public void actionPerformed(ActionEvent e) {
										game.myUI.reenableComponents();
										game.myUI.disableMight();
										if (doneStriking != null) {
											System.out.println("DISPATCHING5");
											doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
													System.currentTimeMillis(), 0, 10, 10, 1, false));
										}
									}
								});
							}
							else if (c instanceof Button && ((Button)c).getLabel().equals("Use fate")) {
								((Button)c).addActionListener(new ActionListener() {
									public void actionPerformed(ActionEvent e) {
										game.myUI.doneUsingMight.addActionListener(new ActionListener() {
											public void actionPerformed(ActionEvent e) {
												game.myUI.reenableComponents();
												game.myUI.disableMight();
												if (doneStriking != null){
													System.out.println("DISPATCHING6");
													doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
															System.currentTimeMillis(), 0, 10, 10, 1, false));
												}
											}
										});
									}
								});
							}
						}
					}
				}
			};
			game.myUI.enableMight(mightDone);
		}
	}
	public void strike(Unit target, boolean hasRetreated, Button doneStriking) {
		if (hasRetreated){
			this.strike(target, doneStriking);
			return;
		}
		// Otherwise, we're trapped
		game.myUI.storeVisibleComponents();
		game.myUI.disableComponents();
		
		int effectiveStrengthTemp;
		// If we have Anduril, maximum required to wound is 4+, which is equivalent to saying we have equal strength and defense
		if (this.hasEquipment(new Anduril()))
			effectiveStrengthTemp = Math.max(this.getStrength(), target.getDefense());
		else
			effectiveStrengthTemp = this.getStrength();
		
		final int effectiveStrength = effectiveStrengthTemp;
		
		int neededToWound = Utils.neededToWound(effectiveStrength, target.getDefense());
		DieRoll strikeRoll1 = new DieRoll(this, game.myUI.dim.width-200, game.myUI.dim.height/2-130, 
										 this.woundBonus, neededToWound+"+ to wound", game.myUI);
		DieRoll strikeRoll2 = new DieRoll(this, game.myUI.dim.width-200, game.myUI.dim.height/2-160, 
				 						 this.woundBonus, neededToWound+"+ to wound", game.myUI);

		
		// Can't use might for strike
		if (!strikeRoll1.isModifiable() && !strikeRoll2.isModifiable()) {
			UI.messageLog.add(this.toChoiceString() + " is attacking trapped " 
					+ target.toChoiceString() + " with rolls of " + strikeRoll1.getRoll() + " " + strikeRoll2.getRoll());
			target.takeStrike(effectiveStrength, strikeRoll1.getRoll());
			if (game.myUI.getByName("fateButton") == null) {
				target.takeStrike(strength, strikeRoll2.getRoll());
				if (game.myUI.getByName("fateButton") == null) {
					strikeRoll1.cleanup();
					strikeRoll2.cleanup();
					game.myUI.reenableComponents();
					if (doneStriking != null)
						doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
								System.currentTimeMillis(), 0, 10, 10, 1, false));
				}
				else {
					for (Component c : game.myUI.getComponents()) {
						if (c instanceof Button && ((Button)c).getLabel().equals("Don't use fate")) {
							((Button)c).addActionListener(new ActionListener() {
								public void actionPerformed(ActionEvent e) {
									strikeRoll1.cleanup();
									strikeRoll2.cleanup();
									game.myUI.reenableComponents();
									if (doneStriking != null)
										doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
												System.currentTimeMillis(), 0, 10, 10, 1, false));
								}
							});
						}
						else if (c instanceof Button && ((Button)c).getLabel().equals("Use fate")) {
							((Button)c).addActionListener(new ActionListener() {
								public void actionPerformed(ActionEvent e) {
									game.myUI.doneUsingMight.addActionListener(new ActionListener() {
										public void actionPerformed(ActionEvent e) {
											strikeRoll1.cleanup();
											strikeRoll2.cleanup();
											game.myUI.reenableComponents();
											if (doneStriking != null)
												doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
														System.currentTimeMillis(), 0, 10, 10, 1, false));
										}
									});
								}
							});
						}
					}
				}
			}
			else {
				for (Component c : game.myUI.getComponents()) {
					if (c instanceof Button && ((Button)c).getLabel().equals("Don't use fate")) {
						((Button)c).addActionListener(new ActionListener() {
							public void actionPerformed(ActionEvent e) {
								target.takeStrike(effectiveStrength, strikeRoll2.getRoll());
								if (game.myUI.getByName("fateButton") == null) {
									strikeRoll1.cleanup();
									strikeRoll2.cleanup();
									game.myUI.reenableComponents();
									if (doneStriking != null)
										doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
												System.currentTimeMillis(), 0, 10, 10, 1, false));
								}
								else {
									for (Component c : game.myUI.getComponents()) {
										if (c instanceof Button && ((Button)c).getLabel().equals("Don't use fate")) {
											((Button)c).addActionListener(new ActionListener() {
												public void actionPerformed(ActionEvent e) {
													strikeRoll1.cleanup();
													strikeRoll2.cleanup();
													game.myUI.reenableComponents();
													if (doneStriking != null)
														doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
																System.currentTimeMillis(), 0, 10, 10, 1, false));
												}
											});
										}
										else if (c instanceof Button && ((Button)c).getLabel().equals("Use fate")) {
											((Button)c).addActionListener(new ActionListener() {
												public void actionPerformed(ActionEvent e) {
													game.myUI.doneUsingMight.addActionListener(new ActionListener() {
														public void actionPerformed(ActionEvent e) {
															strikeRoll1.cleanup();
															strikeRoll2.cleanup();
															game.myUI.reenableComponents();
															if (doneStriking != null)
																doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
																		System.currentTimeMillis(), 0, 10, 10, 1, false));
														}
													});
												}
											});
										}
									}
								}
								game.myUI.reenableComponents();
							}
						});
					}
					else if (c instanceof Button && ((Button)c).getLabel().equals("Use fate")) {
						((Button)c).addActionListener(new ActionListener() {
							public void actionPerformed(ActionEvent e) {
								game.myUI.doneUsingMight.addActionListener(new ActionListener() {
									public void actionPerformed(ActionEvent e) {
										target.takeStrike(effectiveStrength, strikeRoll2.getRoll());
										if (game.myUI.getByName("fateButton") == null) {
											strikeRoll1.cleanup();
											strikeRoll2.cleanup();
											game.myUI.reenableComponents();
											if (doneStriking != null)
												doneStriking.dispatchEvent(null);
										}
										else {
											for (Component c : game.myUI.getComponents()) {
												if (c instanceof Button && ((Button)c).getLabel().equals("Don't use fate")) {
													((Button)c).addActionListener(new ActionListener() {
														public void actionPerformed(ActionEvent e) {
															strikeRoll1.cleanup();
															strikeRoll2.cleanup();
															game.myUI.reenableComponents();
															if (doneStriking != null)
																doneStriking.dispatchEvent(null);
														}
													});
												}
												else if (c instanceof Button && ((Button)c).getLabel().equals("Use fate")) {
													((Button)c).addActionListener(new ActionListener() {
														public void actionPerformed(ActionEvent e) {
															game.myUI.doneUsingMight.addActionListener(new ActionListener() {
																public void actionPerformed(ActionEvent e) {
																	strikeRoll1.cleanup();
																	strikeRoll2.cleanup();
																	game.myUI.reenableComponents();
																	if (doneStriking != null)
																		doneStriking.dispatchEvent(null);
																}
															});
														}
													});
												}
											}
										}
										game.myUI.reenableComponents();
									}
								});
							}
						});
					}
				}
			}
			/*game.myUI.reenableComponents();
			if (doneStriking != null)
				doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
						System.currentTimeMillis(), 0, 10, 10, 1, false));*/
		}
		else {
			ActionListener mightDone = new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					UI.messageLog.add(toChoiceString() + " is attacking trapped " 
							+ target.toChoiceString() + " with rolls of " + strikeRoll1.getRoll()+ " " + strikeRoll2.getRoll());
					target.takeStrike(effectiveStrength, strikeRoll1.getRoll());
					if (game.myUI.getByName("fateButton") == null) {
						target.takeStrike(strength, strikeRoll2.getRoll());
						if (game.myUI.getByName("fateButton") == null) {
							strikeRoll1.cleanup();
							strikeRoll2.cleanup();
							game.myUI.reenableComponents();
							game.myUI.disableMight();
							if (doneStriking != null)
								doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
										System.currentTimeMillis(), 0, 10, 10, 1, false));
						}
						else {
							for (Component c : game.myUI.getComponents()) {
								if (c instanceof Button && ((Button)c).getLabel().equals("Don't use fate")) {
									((Button)c).addActionListener(new ActionListener() {
										public void actionPerformed(ActionEvent e) {
											strikeRoll1.cleanup();
											strikeRoll2.cleanup();
											game.myUI.reenableComponents();
											game.myUI.disableMight();
											if (doneStriking != null)
												doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
														System.currentTimeMillis(), 0, 10, 10, 1, false));
										}
									});
								}
								else if (c instanceof Button && ((Button)c).getLabel().equals("Use fate")) {
									((Button)c).addActionListener(new ActionListener() {
										public void actionPerformed(ActionEvent e) {
											game.myUI.doneUsingMight.addActionListener(new ActionListener() {
												public void actionPerformed(ActionEvent e) {
													strikeRoll1.cleanup();
													strikeRoll2.cleanup();
													game.myUI.reenableComponents();
													game.myUI.disableMight();
													if (doneStriking != null)
														doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
																System.currentTimeMillis(), 0, 10, 10, 1, false));
												}
											});
										}
									});
								}
							}
						}
					}
					else {
						for (Component c : game.myUI.getComponents()) {
							if (c instanceof Button && ((Button)c).getLabel().equals("Don't use fate")) {
								((Button)c).addActionListener(new ActionListener() {
									public void actionPerformed(ActionEvent e) {
										target.takeStrike(effectiveStrength, strikeRoll2.getRoll());
										if (game.myUI.getByName("fateButton") == null) {
											strikeRoll1.cleanup();
											strikeRoll2.cleanup();
											game.myUI.reenableComponents();
											game.myUI.disableMight();
											if (doneStriking != null)
												doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
														System.currentTimeMillis(), 0, 10, 10, 1, false));
										}
										else {
											for (Component c : game.myUI.getComponents()) {
												if (c instanceof Button && ((Button)c).getLabel().equals("Don't use fate")) {
													((Button)c).addActionListener(new ActionListener() {
														public void actionPerformed(ActionEvent e) {
															strikeRoll1.cleanup();
															strikeRoll2.cleanup();
															game.myUI.reenableComponents();
															game.myUI.disableMight();
															if (doneStriking != null)
																doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
																		System.currentTimeMillis(), 0, 10, 10, 1, false));
														}
													});
												}
												else if (c instanceof Button && ((Button)c).getLabel().equals("Use fate")) {
													((Button)c).addActionListener(new ActionListener() {
														public void actionPerformed(ActionEvent e) {
															game.myUI.doneUsingMight.addActionListener(new ActionListener() {
																public void actionPerformed(ActionEvent e) {
																	strikeRoll1.cleanup();
																	strikeRoll2.cleanup();
																	game.myUI.reenableComponents();
																	game.myUI.disableMight();
																	if (doneStriking != null)
																		doneStriking.dispatchEvent(new MouseEvent(doneStriking, MouseEvent.MOUSE_CLICKED, 
																				System.currentTimeMillis(), 0, 10, 10, 1, false));
																}
															});
														}
													});
												}
											}
										}
										/*
										game.myUI.reenableComponents();
										game.myUI.disableMight();*/
									}
								});
							}
							else if (c instanceof Button && ((Button)c).getLabel().equals("Use fate")) {
								((Button)c).addActionListener(new ActionListener() {
									public void actionPerformed(ActionEvent e) {
										game.myUI.doneUsingMight.addActionListener(new ActionListener() {
											public void actionPerformed(ActionEvent e) {
												target.takeStrike(effectiveStrength, strikeRoll2.getRoll());
												if (game.myUI.getByName("fateButton") == null) {
													strikeRoll1.cleanup();
													strikeRoll2.cleanup();
													game.myUI.reenableComponents();
													game.myUI.disableMight();
													if (doneStriking != null)
														doneStriking.dispatchEvent(null);
												}
												else {
													for (Component c : game.myUI.getComponents()) {
														if (c instanceof Button && ((Button)c).getLabel().equals("Don't use fate")) {
															((Button)c).addActionListener(new ActionListener() {
																public void actionPerformed(ActionEvent e) {
																	strikeRoll1.cleanup();
																	strikeRoll2.cleanup();
																	game.myUI.reenableComponents();
																	game.myUI.disableMight();
																	if (doneStriking != null)
																		doneStriking.dispatchEvent(null);
																}
															});
														}
														else if (c instanceof Button && ((Button)c).getLabel().equals("Use fate")) {
															((Button)c).addActionListener(new ActionListener() {
																public void actionPerformed(ActionEvent e) {
																	game.myUI.doneUsingMight.addActionListener(new ActionListener() {
																		public void actionPerformed(ActionEvent e) {
																			strikeRoll1.cleanup();
																			strikeRoll2.cleanup();
																			game.myUI.reenableComponents();
																			game.myUI.disableMight();
																			if (doneStriking != null)
																				doneStriking.dispatchEvent(null);
																		}
																	});
																}
															});
														}
													}
												}
												/*game.myUI.reenableComponents();
												game.myUI.disableMight();*/
											}
										});
									}
								});
							}
						}
					}
				}
			};
			game.myUI.enableMight(mightDone);
		}
	}

}
